package com.xiaodao.zk.service;

import com.alibaba.fastjson.JSONObject;
import com.xiaodao.zk.entity.Jdbc;
import org.I0Itec.zkclient.IZkChildListener;
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.IZkStateListener;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.serialize.SerializableSerializer;
import org.apache.zookeeper.Watcher;
import org.springframework.stereotype.Service;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

/**
 * @ClassName : ZkService
 * @Description : TODO
 * @Author : xiaodao
 * @Date : 2018/11/21  0:00
 * @Version : 1.0
 **/
@Service
public class ZkService<T> {
    Properties prop = new Properties();


    public List<String> list =  new ArrayList();

    private String connectString = "119.29.199.151:2181";
    ZkClient zkClient =  new ZkClient(connectString, 5000, 5000, new SerializableSerializer());

    public ZkService() throws FileNotFoundException {
    }

    public T readData(String path) {
        return zkClient.readData(path);

    }

    public List<String> getChildren(String path) {
        return zkClient.getChildren(path);
    }

    public T writeData(String path, Object object) {
        zkClient.writeData(path, object);
        return zkClient.readData(path);
    }

    public void deleteRecursive(String path) {
        zkClient.deleteRecursive(path);
    }
    public boolean  existPath(String path){
       return zkClient.exists(path);
    }

    /***
     * @param path
     * @param data
     */
    public T createPersistent(String path, Object data) {
        lister(path);
        zkClient.createPersistent(path, data);
        return zkClient.readData(path);
    }
    public void lister(String path) {
        //对父节点添加监听变化。
        zkClient.subscribeDataChanges(path, new IZkDataListener() {
            @Override
            public void handleDataChange(String dataPath, Object data) throws Exception {
                FileOutputStream oFile = new FileOutputStream("a.properties", false);//true表示追加打开
                Jdbc jd  = (Jdbc) data;
                prop.setProperty("username",jd.getUserName());
                prop.setProperty("password",jd.getPassword());
                prop.store(oFile, "The New properties file");
                oFile.close();
                System.out.printf("变更的节点为:%s,%s", dataPath, data);
            }

            @Override
            public void handleDataDeleted(String dataPath) throws Exception {
                System.out.printf("删除的节点为:%s", dataPath);
            }
        });
        //对父节点添加监听子节点变化。
        zkClient.subscribeChildChanges(path, new IZkChildListener() {
            @Override
            public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception {
                System.out.println("parentPath: " + parentPath + ",currentChilds:" + currentChilds);
            }
        });
        //对父节点添加监听子节点变化。
        zkClient.subscribeStateChanges(new IZkStateListener() {
            @Override
            public void handleStateChanged(Watcher.Event.KeeperState state) throws Exception {
                if (state == Watcher.Event.KeeperState.SyncConnected) {
                    //当我重新启动后start，监听触发
                    System.out.println("连接成功");
                } else if (state == Watcher.Event.KeeperState.Disconnected) {
                    //当我在服务端将zk服务stop时，监听触发
                    System.out.println("连接断开") ;

                    if(zkClient!=null){
                        zkClient.close();
                    }else{
                        zkClient =   new ZkClient(connectString, 5000, 5000, new SerializableSerializer());
                        for (String item:zkClient.getChildren("/")  ) {
                            lister("/"+item);
                        }
                    }

                } else{
                    System.out.println("其他状态" + state);
                }
            }

            @Override
            public void handleNewSession() throws Exception {
                System.out.println("重建session");
            }


        });

    }

}
